/******************************************************************************
	This file is a part of the Snapshot Bioinformatics Project

	Copyright (C) 2012-2013 Jarom Schow

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

#include "Progress.h"

#include "ProgressHandler.h"

using namespace Bio;

/**
	Private Data Class for Progress.
**/
class ProgressData {
public:
	ProgressData() : m_progHandler( NULL ) { }
	~ProgressData() 
	{ 
		delete m_progHandler; m_progHandler = NULL;
	}

	ProgressHandler		*m_progHandler;
};

static ProgressData	s_data;

///////////////////////////////////////////////////////////////////////////////
//	Progress
///////////////////////////////////////////////////////////////////////////////

/**
	@class Progress
	@brief Class that manages a progress report.

	This class provides the functionality needed to report progress to the user.
**/

/**
	General Constructor. Starts a new progress report for an operation.
	@param	msg			The message to display on the progress report.
	@param	totalSteps	The total number of steps for the operation.
	@param	canCancel	Whether or not the user can cancel the operation.
**/
Progress::Progress( const QString &msg, int totalSteps, bool canCancel ) : m_item( NULL )
{
	if( s_data.m_progHandler )
		m_item = s_data.m_progHandler->startProgress( msg, totalSteps, canCancel );
}

/**
	Destructor
**/
Progress::~Progress()
{
	delete m_item;
	m_item = NULL;
}

/**
	Get the 'canceled' state of the progress operation.
	@return true if the user has canceled the current operation, otherwise false.
**/
bool Progress::isCanceled() const
{
	if( m_item )
		return m_item->isCanceled();

	return false;
}

/**
	Step the progress operation. The given number of steps is added to the current
	number of steps to determine the position of the progress indicator.
	@param	steps	The number of steps to move progress forward.
**/
void Progress::step( int steps )
{
	if( m_item )
		return m_item->step( steps );
}

/**
	Set the position of the progress indicator.
	@param	curSteps	The number of steps to set the progress indicator position to.
**/
void Progress::update( int curSteps )
{
	if( m_item )
		return m_item->update( curSteps );
}

/**
	End the current progress operation.
**/
void Progress::finish()
{
	if( m_item )
		return m_item->finish();
}

/**
	Cancel the current progress operation. This can be used to programatically signal
	a cancelling of the operation as if the user clicked the 'Cancel' button.
**/
void Progress::cancel()
{
	if( m_item )
		return m_item->cancel();
}

/**
	Set the current message displayed by the progress indicator.
	@param	msg	The new message to display on the progress indicator.
**/
void Progress::status( const QString &msg )
{
	if( m_item )
		return m_item->status( msg );
}

/**
	Sets the progress handler that will handle all progress operations for the application.
	Applications can provide their own implementation of a progress handler by implementing
	the ProgressHandler interface and passing an instance to this function. The Bio library
	takes ownership of this object and deletes it when the library is shut down or a new
	handler is given.
	@param	progHandler	The progress handler that will manage progress events for the application.
**/
void Progress::setProgressHandler( ProgressHandler *progHandler )
{
	delete s_data.m_progHandler;
	s_data.m_progHandler = progHandler;
}
